<?php
require_once(DIR_LIBRARY."orm".DS."orm.php");
/**
 * this is common thread post framework for thread and post application
 *
 */
class CtpThread extends ORM
{
    const APP_NICE  = 1;
    const APP_FORUM = 2;
    const STATUS_AVAILABLE = 1;
    const STATUS_DELETED   = 2;
    const DEFAULT_PAGE_SIZE = 20;

    public static $apps = array(
        "nice"  => self::APP_NICE,    
        "forum" => self::APP_FORUM,
    );

    private static $instance;

    protected $dsn       = "default";
    protected $tablename = "thread";
    protected $rebuildTableName = true;
    protected $validFields = array("id", "app", "shard", "sequence", "type", "status", "created", "updated", "creator");


    public function __construct($id = NULL)
    {
        parent::__construct($id);
    }

   public function getThread($app, $sequence = 0, $thread_id = 0)
   {
       $this->setApp($app);
       if ($thread_id)
       {
            $this->setId($thread_id);
       }
       else if ($sequence)
       {
            $this->setSequence($sequence);
       }
       else
       {
            throw new Exception("no thread id or sequence");
       }

       $this->load();

       return $this;
    }

	public function getListBySequence($app, $sequence = 1, $page_size = self::DEFAULT_PAGE_SIZE, $condition = array())
	{
		if (!$app)
		{
			throw new Exception("no app");
		}

        $this->setApp($app);
		return parent::getListBySequence($sequence, $page_size, $condition);	
	}


    public function create()
    {
        //check  first
        $app      = $this->getApp();
        $creator  = $this->getCreator();
		$type     = $this->getType();

        if (!$app)
        {
            throw new Exception("no app");
        }

        if (!$creator)
        {
            throw new Exception("no creator");
        }

        if (!$type)
        {
            throw new Exception("no type");
        }

        $time = time();

        $thread = self::factory();
        $thread->setApp($app);
        $sequence = $thread->getMax("sequence") + 1;
        unset($thread);
        $shard    = $this->generateShard($app, $time);
        $this->setSequence($sequence);
        $this->setShard($shard);
        $this->setStatus(self::STATUS_AVAILABLE);
        $this->setCreated($time);
        $this->setUpdated($time);

        //create
        return parent::create();
    }

    public function rebuildTableName()
    {
		return $this->tablename."_".$this->getApp();
    }

    public function updateBySequence($app, $sequence)
    {
        return $this->update($app, $sequence);
    }

    public function updateById($app, $id)
    {
        return $this->update($app, NULL, $id);
    }

    public function update($app, $sequence = NULL, $id = NULL)
    {
        $this->setApp($app);
        $this->appendWhere("app=".$app);

        if (!$sequence && !$id)
        {
            throw new Exception("no sequence or id");
        }

        if ($sequence)
        {
            $this->appendWhere("sequence=".$sequence);
        }

        if ($id)
        {
            $this->appendWhere("id=".$id);
        }

        $time = time();
        $this->setUpdated($time);
        
        //update
        return parent::update();
    }

    public function deleteBySequence($app, $sequence)
    {
        return $this->delete($app, $sequence);
    }

    public function deleteById($app, $id)
    {
        return $this->delete($app, NULL, $id);
    }

    public function delete($app, $sequence = NULL, $id = NULL)
    {
        $this->setApp($app);
        $this->appendWhere("app=".$app);

        if (!$sequence && !$id)
        {
            throw new Exception("no sequence or id");
        }

        if ($sequence)
        {
            $this->appendWhere("sequence=".$sequence);
        }

        if ($id)
        {
            $this->appendWhere("id=".$id);
        }

        $this->setStatus(self::STATUS_DELETED);

        return parent::update();
    }

    public function generateShard($app, $time)
    {
        return $app;
    }

    public static function factory($id = NULL)
    {
        return new self($id);
    }

    public static function getInstance()
    {
        if (!self::$instance)
        {
            self::$instance = new self();
        }

        return self::$instance;
    }
    
} //end class
